import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MenuListener;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.zest.core.widgets.Graph;

/**
 * 
 * Container class for the menus and menu items in the MapEditor UI
 *
 */
public class BaphiMenus {
	Display d;
	Shell shell;
	Graph g;
	
	// Helper/Utility classes. Not elegant, but functional.
	BaphiDialogs bd;
	NodeUtils nu;
	BaphiFileHandler bfh;
	BaphiListeners bl;
	
	Menu popMenu;
	Menu bar;
	
	Menu subPopMenu, fileMenu, editMenu;
	MenuItem newNode, renameNode, deleteNode, setColor;
	MenuItem selectAll;
	MenuItem newMap, open, save, exitApp;
	MenuItem subPopItem[], fileBarItem, editBarItem;
	
	/**
	 * Container class for the menus and menu items in the MapEditor UI. You pass a bunch of crufty utility classes in. Bleah.
	 * @param d
	 * @param shell
	 * @param g
	 * @param bd
	 * @param nu
	 * @param bfh
	 */
	BaphiMenus(Display d, Shell shell, Graph g, BaphiDialogs bd, NodeUtils nu, BaphiFileHandler bfh)
	{
		this.d = d;
		this.shell = shell;
		this.g = g;
		this.bd = bd;
		this.nu = nu;
		this.bfh = bfh;
		
		// Set up the Listener classes that actually do all the work
		bl = new BaphiListeners(d, shell, g, bd, nu, bfh);

		g.addMouseListener(new BaphiListeners.GraphMouseListener());

		// Populate the menus
		mapMenus();
	}

	// It was much easier to stick this listener here rather than in BaphiListeners, since it relies on data 
	// local to BaphiMenus.
	class PopupMenu implements  MenuListener {

		public void menuHidden(MenuEvent e) {
		}

		public void menuShown(MenuEvent e) {
			
			// If we don't currently have a node selected only Create Node should be enabled in the pop-up menu.
			if (g.getSelection().isEmpty())
			{
				popMenu.getItem(0).setEnabled(true);
				popMenu.getItem(1).setEnabled(false);
				popMenu.getItem(2).setEnabled(false);
				popMenu.getItem(3).setEnabled(false);
			}
			else // Otherwise Create node should be disabled.
			{
				popMenu.getItem(0).setEnabled(false);
				popMenu.getItem(1).setEnabled(true);
				popMenu.getItem(2).setEnabled(true);
				popMenu.getItem(3).setEnabled(true);
			}				
		}
	};
	
	/**
	 * Populate menu bars and items
	 */
	void mapMenus()
	{
		popMenu = new Menu(shell, SWT.POP_UP);
		bar = new Menu (shell, SWT.BAR);
		
		// Set the menu items in the pop-up menu
		newNode = new MenuItem(popMenu, SWT.PUSH);
		newNode.setText("New Node");
		renameNode = new MenuItem(popMenu, SWT.PUSH);
		renameNode.setText("Rename");
		deleteNode = new MenuItem(popMenu, SWT.PUSH);
		deleteNode.setText("Delete");
		setColor = new MenuItem(popMenu, SWT.CASCADE);
		setColor.setText("Set Color");
		g.setMenu(popMenu);			
		subPopMenu = new Menu(popMenu);
		subPopItem = new MenuItem[6];
		
		// Iterate through the colors and populate the color menu items
		for (int i = 0; i < subPopItem.length; i++)
		{
			subPopItem[i] = new MenuItem (subPopMenu, SWT.PUSH);
			subPopItem[i].setText(nu.getColorString(i));
			subPopItem[i].setData(nu.colorLookup(i));
		}
		setColor.setMenu(subPopMenu);

		shell.setMenuBar(bar);
		
		// Populate the File menu with the usual suspects
		fileBarItem = new MenuItem (bar, SWT.CASCADE);
		fileBarItem.setText("&File");
		fileMenu = new Menu(shell, SWT.DROP_DOWN);
		fileBarItem.setMenu(fileMenu);

		newMap = new MenuItem (fileMenu, SWT.PUSH);
		newMap.setText ("&New Map...\tCtrl+N");
		newMap.setAccelerator (SWT.MOD1 + 'N');
		
		open = new MenuItem (fileMenu, SWT.PUSH);
		open.setText ("&Open Map...\tCtrl+O");
		open.setAccelerator (SWT.MOD1 + 'O');
		
		save = new MenuItem (fileMenu, SWT.PUSH);
		save.setText ("&Save Map...\tCtrl+S");
		save.setAccelerator (SWT.MOD1 + 'S');

		// Let Exit be Alt-F4
		// TODO Find out which MODn is Alt
		exitApp = new MenuItem (fileMenu, SWT.PUSH);
		exitApp.setText ("E&xit\tAlt+F4");
		// exitApp.setAccelerator (SWT.MOD1 + 'S');
		
		// Create and populate the Edit menu
		editBarItem = new MenuItem (bar, SWT.CASCADE);
		editBarItem.setText ("&Edit");
		editMenu = new Menu(shell, SWT.DROP_DOWN);
		editBarItem.setMenu(editMenu);
		
		selectAll = new MenuItem (editMenu, SWT.PUSH);
		selectAll.setText ("Select &All\tCtrl+A");
		selectAll.setAccelerator (SWT.MOD1 + 'A');

		// Hook up all the menu and menu item listeners
		popMenu.addMenuListener(new PopupMenu());
		newNode.addSelectionListener(new BaphiListeners.PopupNewNode());
		renameNode.addSelectionListener(new BaphiListeners.PopupRenameNode());
		deleteNode.addSelectionListener(new BaphiListeners.PopupDeleteNode());
		
		for (MenuItem mi : subPopItem)
			mi.addSelectionListener(new BaphiListeners.ColorMenuItem());

		newMap.addSelectionListener(new BaphiListeners.NewMap());
		open.addSelectionListener(new BaphiListeners.Open());
		save.addSelectionListener(new BaphiListeners.Save());
		selectAll.addSelectionListener(new BaphiListeners.SelectAll());
	}
}
